package com.zbkj.service.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.zbkj.common.constants.CashRecordConstants;
import com.zbkj.common.constants.Constants;
import com.zbkj.common.constants.CouponConstants;
import com.zbkj.common.constants.RedisConstatns;
import com.zbkj.common.exception.CrmebException;
import com.zbkj.common.model.card.StoreGiftCard;
import com.zbkj.common.model.card.StoreGiftCardUser;
import com.zbkj.common.model.category.Category;
import com.zbkj.common.model.product.StoreProduct;
import com.zbkj.common.model.system.SystemAdmin;
import com.zbkj.common.model.user.User;
import com.zbkj.common.model.user.UserCashRecord;
import com.zbkj.common.page.CommonPage;
import com.zbkj.common.request.PageParamRequest;
import com.zbkj.common.request.StoreGiftCardRequest;
import com.zbkj.common.request.StoreGiftCardUserSearchRequest;
import com.zbkj.common.request.UserGiftCardReceiveRequest;
import com.zbkj.common.response.StoreGiftCardInfoResponse;
import com.zbkj.common.response.StoreGiftCardUserResponse;
import com.zbkj.common.utils.CrmebUtil;
import com.zbkj.common.utils.DateUtil;
import com.zbkj.common.utils.RedisUtil;
import com.zbkj.common.utils.SecurityUtil;
import com.zbkj.common.vo.GiftCardExportVo;
import com.zbkj.common.vo.MyRecord;
import com.zbkj.service.dao.StoreGiftCardDao;
import com.zbkj.service.dao.StoreGiftCardUserDao;
import com.zbkj.service.service.*;
import com.zbkj.service.util.SnowflakeIdWorker;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.*;
import java.util.stream.Collectors;

/**
 * StoreGiftCardUser 服务层接口实现
 *
 * @author Swallows
 * @date 2022-08-22 08:53
 */
@Service
@RequiredArgsConstructor
public class StoreGiftCardUserServiceImpl extends ServiceImpl<StoreGiftCardUserDao, StoreGiftCardUser> implements StoreGiftCardUserService {

    private final StoreGiftCardUserDao dao;
    private final StoreGiftCardDao giftCardDao;
    private final StoreProductService storeProductService;
    private final SystemConfigService systemConfigService;
    private final SystemAdminService systemAdminService;
    private final CategoryService categoryService;
    private final UserService userService;

    private final RedisUtil redisUtil;

    private final TransactionTemplate transactionTemplate;
    private final UserCashRecordService userCashRecordService;

    @Override
    public boolean draw(String key) throws Exception {

//        初始化加解解密实例
        SymmetricCrypto symmetricCrypto = new SymmetricCrypto(SymmetricAlgorithm.AES, Constants.GIFT_CARD_SHARE_KEY.getBytes());
        String cardNum = symmetricCrypto.decryptStr(key).substring(0,18);
        LambdaQueryWrapper<StoreGiftCardUser> lqw = Wrappers.lambdaQuery();
        lqw.eq(StoreGiftCardUser::getCardNum, cardNum);
        lqw.eq(StoreGiftCardUser::getReceiveStatus, 2);
        StoreGiftCardUser cardInfo = dao.selectOne(lqw);

        if (ObjectUtil.isNull(cardInfo)) {
            throw new CrmebException("无该卡片信息");
        }

        if (ObjectUtil.isNotNull(cardInfo.getUid())) {
            throw new CrmebException("该卡已经被领取,无法再次赠送");
        }

        if (cardInfo.getStatus() > 0) {
            throw new CrmebException("该卡已使用或者过期");
        }
        if (DateUtil.nowDateTime().getTime() - cardInfo.getExpiredTime().getTime() > 0) {
            throw new CrmebException("已过领取有效期");
        }

        Integer uid = userService.getUserId();
        cardInfo.setUid(uid);
        cardInfo.setReceiveStatus(3);
        cardInfo.setReceiveTime(DateUtil.nowDateTimeReturnDate(Constants.DATE_FORMAT));

        return dao.updateById(cardInfo) > 0;
    }

    @Override
    public String getShareKey(Integer cardId) {

        LambdaQueryWrapper<StoreGiftCardUser> lqw = Wrappers.lambdaQuery();
        lqw.eq(StoreGiftCardUser::getId, cardId);
        Integer uid = userService.getUserId();
        lqw.eq(StoreGiftCardUser::getBelongId, uid);

        StoreGiftCardUser cardInfo = dao.selectOne(lqw);
        if (ObjectUtil.isNull(cardInfo)) {
            throw new CrmebException("名下没有此卡");
        }

        if (ObjectUtil.isNotNull(cardInfo.getUid()) || cardInfo.getReceiveStatus() != 1) {
            throw new CrmebException("无法重复赠送");
        }

        if (cardInfo.getStatus() > 0) {
            throw new CrmebException("该卡已使用或者过期");
        }

//        获取礼品卡领取过期时间配置
        String expiredTime = DateUtil.addSecond(DateUtil.nowDateTimeReturnDate(Constants.DATE_FORMAT),
                Integer.parseInt(systemConfigService.getValueByKey(Constants.GIFT_CARD_SHARE_EXPIRE)) * 60 * 60,
                Constants.DATE_FORMAT);

        cardInfo.setReceiveStatus(2);
        cardInfo.setExpiredTime(DateUtil.strToDate(expiredTime, Constants.DATE_FORMAT));
        if (dao.updateById(cardInfo) > 0) {
//            初始化加密实例
            SymmetricCrypto symmetricCrypto = new SymmetricCrypto(SymmetricAlgorithm.AES, Constants.GIFT_CARD_SHARE_KEY.getBytes());
            return symmetricCrypto.encryptHex(cardInfo.getCardNum() + DateUtil.nowDateTime().getTime());
        } else {
            return null;
        }
    }

    @Override
    public boolean verification() {

//        1.获取当前用户id
        User user = userService.getInfo();
//        2.根据用户id获取当前已经验证过卡密的卡id
        Integer cardId = redisUtil.get(RedisConstatns.USER_USE_GIFT_CARD_KEY + user.getUid());
//        3.判断cardId是否为空
        if (cardId == null) {
            throw new CrmebException("没有找到有效的卡密验证信息,请重试");
        }
//        4.查询该卡详情并判断是否有效
        StoreGiftCardUser giftCardUser = getById(cardId);
        if (ObjectUtil.isNull(giftCardUser)) {
            throw new CrmebException("查询不到该卡片信息");
        }
        Date nowDate = DateUtil.nowDateTime();
        if (giftCardUser.getStatus() != 0 || !(nowDate.after(giftCardUser.getStartTime()) && nowDate.before(giftCardUser.getEndTime()))) {
            throw new CrmebException("该卡片已使用或者不在有效期内");
        }
//        5.向用户账户礼金中进行充值 并判断有无绑定推广人
        user.setCash(user.getCash() + giftCardUser.getMoney().intValue());
        if (user.getSpreadUid() == Constants.NUM_ZERO && giftCardUser.getBelongId() != null) {
            user.setSpreadUid(giftCardUser.getBelongId());
        }
//        6.添加礼金记录
        UserCashRecord record = new UserCashRecord();
        record.setUid(user.getUid());
        record.setLinkId(giftCardUser.getId().toString());
        record.setLinkType(CashRecordConstants.CASH_RECORD_LINK_TYPE_EXCHANGE);
        record.setType(CashRecordConstants.CASH_RECORD_TYPE_ADD);
        record.setStatus(CashRecordConstants.CASH_RECORD_STATUS_COMPLETE);
        record.setBalance(user.getCash());
        record.setCash(giftCardUser.getMoney().intValue());
        record.setTitle(CashRecordConstants.BROKERAGE_RECORD_TITLE_EXCHANGE);
        record.setMark(StrUtil.format("用户使用储值卡,账户礼金增加{}元", giftCardUser.getMoney()));

//        7.更新该礼品卡
        giftCardUser.setStatus(Constants.NUM_ONE);
        giftCardUser.setUid(user.getUid());
        giftCardUser.setUseTime(DateUtil.nowDateTime());
        giftCardUser.setUpdateTime(DateUtil.nowDateTime());

        return Boolean.TRUE.equals(transactionTemplate.execute(e -> {
//            更新卡片信息
            dao.updateById(giftCardUser);
//            更新用户信息
            userService.updateById(user);
//            保存礼金记录
            userCashRecordService.save(record);
            return Boolean.TRUE;
        }));
    }

    @Override
    public PageInfo<StoreGiftCardUserResponse> getPageList(StoreGiftCardUserSearchRequest searchRequest, PageParamRequest pageParamRequest) {

        Page<StoreGiftCardUser> storeGiftCardUsers = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());

        LambdaQueryWrapper<StoreGiftCardUser> lqw = new LambdaQueryWrapper<>();
        if (!StringUtils.isBlank(searchRequest.getName())) {
            lqw.like(StoreGiftCardUser::getName, searchRequest.getName());
        }

        if (searchRequest.getUid() !=null && searchRequest.getUid() > 0) {
            lqw.eq(StoreGiftCardUser::getUid, searchRequest.getUid());
        }

        if (searchRequest.getStatus() !=null) {
            lqw.eq(StoreGiftCardUser::getStatus, searchRequest.getStatus());
        }
        if (searchRequest.getCardId() != null) {
            lqw.eq(StoreGiftCardUser::getCardId, searchRequest.getCardId());
        }
        if (searchRequest.getReceiveStatus() != null) {
            lqw.eq(StoreGiftCardUser::getReceiveStatus, searchRequest.getReceiveStatus());
        }
        lqw.orderByDesc(StoreGiftCardUser::getId);

        List<StoreGiftCardUser> cardUserList = dao.selectList(lqw);
        if (cardUserList.size() < 1) {
            return new PageInfo<>();
        }

        ArrayList<StoreGiftCardUserResponse> cardUserResponses = new ArrayList<>();
        List<Integer> uidList = cardUserList.stream()
                .map(StoreGiftCardUser::getUid)
                .distinct()
                .collect(Collectors.toList());
        List<Integer> belongIdList = cardUserList.stream()
                .map(StoreGiftCardUser::getBelongId)
                .distinct()
                .collect(Collectors.toList());
        List<Integer> operIdList = cardUserList.stream()
                .map(StoreGiftCardUser::getOperId)
                .distinct()
                .collect(Collectors.toList());
        HashMap<Integer, User> userList = userService.getMapListInUid(uidList);
        HashMap<Integer, User> belongUserList = userService.getMapListInUid(belongIdList);
        HashMap<Integer, SystemAdmin> systemUserList = systemAdminService.getMapInId(operIdList);

        for (StoreGiftCardUser cardUser : cardUserList) {
            StoreGiftCardUserResponse response = new StoreGiftCardUserResponse();
            BeanUtil.copyProperties(cardUser, response);
            if (userList.containsKey(cardUser.getUid())) {
                response.setNickname(userList.get(cardUser.getUid()).getNickname());
                response.setAvatar(userList.get(cardUser.getUid()).getAvatar());
            }
            if (belongUserList.containsKey(cardUser.getBelongId())) {
                response.setBelongName(belongUserList.get(cardUser.getBelongId()).getNickname());
            }
            if (systemUserList.containsKey(cardUser.getOperId())) {
                SystemAdmin admin = systemUserList.get(cardUser.getOperId());
                String operName = admin.getRealName();
                response.setOperName(operName);
            }
            cardUserResponses.add(response);
        }
        return CommonPage.copyPageInfo(storeGiftCardUsers, cardUserResponses);
    }

    @Override
    public boolean deliver(String uid, String cardList) {

        Integer operId = SecurityUtil.getLoginUserVo().getUser().getId();

        List<Integer> uidList = CrmebUtil.stringToArray(uid);
        List<Integer> giftCardList = CrmebUtil.stringToArray(cardList);
        if (uidList.size() < 1) {
            throw new CrmebException("请选择用户！");
        }

        List<StoreGiftCardUser> cardUserList = Lists.newArrayList();
        for (Integer userId : uidList) {
            if (userService.getInfoByUid(userId) == null) {
                throw new CrmebException("查无此人");
            }

            for (Integer id : giftCardList) {
                StoreGiftCardUser cardUser = dao.selectById(id);
                if (cardUser == null) {
                    throw new CrmebException(String.format("查询不到该卡片id: %s 信息", id));
                }
                if (cardUser.getBelongId() != null || cardUser.getUid() != null) {
                    throw new CrmebException(String.format("该卡片: %s 已经发放给其他用户", cardUser.getCardNum()));
                }
                if (cardUser.getStatus() != 0 || cardUser.getReceiveStatus() != 0) {
                    throw new CrmebException(String.format("该卡片: %s 不在有效状态", cardUser.getCardNum()));
                }

                cardUser.setOperId(operId);
                cardUser.setBelongId(userId);
                cardUser.setReceiveStatus(1);
                cardUser.setType("send");

                cardUserList.add(cardUser);
            }
        }
        return saveOrUpdateBatch(cardUserList);
    }

    @Override
    public List<GiftCardExportVo> makeCards(StoreGiftCard giftCard, Integer num) {

        SnowflakeIdWorker worker = new SnowflakeIdWorker(giftCard.getCardType(), giftCard.getUseType());

        List<StoreGiftCardUser> insertList = Lists.newArrayList();
        List<GiftCardExportVo> exportList = Lists.newArrayList();

        for (int i = 0; i < num; i++) {
            StoreGiftCardUser cardUser = new StoreGiftCardUser();
            GiftCardExportVo export = new GiftCardExportVo();
            cardUser.setName(giftCard.getName());
            export.setName(giftCard.getName());
            cardUser.setCardId(giftCard.getId());
            cardUser.setCardType(giftCard.getCardType());
            export.setCardType(giftCard.getCardType());
            cardUser.setUseType(giftCard.getUseType());
            export.setUseType(giftCard.getUseType());
            cardUser.setStatus(0);
            cardUser.setPrimaryKey(giftCard.getPrimaryKey());
            cardUser.setMoney(giftCard.getMoney());
            export.setMoney(giftCard.getMoney());
            cardUser.setImage(giftCard.getImage());
            cardUser.setCreateTime(DateUtil.nowDateTime());
            cardUser.setStartTime(giftCard.getUseStartTime());
            cardUser.setEndTime(giftCard.getUseEndTime());

            String cardNum = String.valueOf(worker.nextId());
            cardUser.setCardNum(cardNum);
            export.setCardNum(cardNum);

            if (giftCard.getCardType() == 2) {
                String password = CrmebUtil.randomPassword();
                cardUser.setPass(SecureUtil.sha256(password));
                export.setPass(password);
            }

            insertList.add(cardUser);
            exportList.add(export);
        }

        if (saveOrUpdateBatch(insertList)) {
            return exportList;
        }
        return new ArrayList<>();
    }

    @Override
    public CommonPage<StoreGiftCardUserResponse> getMyGiftCardList(String type, PageParamRequest pageParamRequest) {

        Integer userId = userService.getUserIdException();

        List<StoreGiftCardUser> cardUserList = getH5List(type, userId, pageParamRequest);

        if (CollUtil.isEmpty(cardUserList)) {
            return null;
        }
        Date date = DateUtil.nowDateTime();
        List<StoreGiftCardUserResponse> responseList = CollUtil.newArrayList();
        for (StoreGiftCardUser cardUser :cardUserList) {
            StoreGiftCardUserResponse cardUserResponse = new StoreGiftCardUserResponse();
            BeanUtils.copyProperties(cardUser, cardUserResponse);
            String validStr = "usable";// 可用
            if (cardUser.getStatus().equals(CouponConstants.STORE_COUPON_USER_STATUS_USED)) {
                validStr = "unusable";// 已用
            }
            if (cardUser.getStatus().equals(CouponConstants.STORE_COUPON_USER_STATUS_LAPSED)) {
                validStr = "overdue";// 过期
            }

            //判断是否在使用时间内
            if (null != cardUserResponse.getStartTime() && null != cardUserResponse.getEndTime()) {
                if (cardUserResponse.getStartTime().compareTo(date) > 0) {
                    validStr = "notStart";// 未开始
                }
                if (date.compareTo(cardUserResponse.getEndTime()) >= 0) {
                    validStr = "overdue";// 过期
                }
            }
            cardUserResponse.setValidStr(validStr);

            // 更改使用时间格式，去掉时分秒
            cardUserResponse.setUseStartTimeStr(DateUtil.dateToStr(cardUserResponse.getStartTime(), Constants.DATE_FORMAT_DATE));
            cardUserResponse.setUseEndTimeStr(DateUtil.dateToStr(cardUserResponse.getEndTime(), Constants.DATE_FORMAT_DATE));
            responseList.add(cardUserResponse);
        }
        return CommonPage.restPage(responseList);
    }

    @Override
    public HashMap<Integer, StoreGiftCardUser> getMapByUserId(Integer uid) {

        List<StoreGiftCardUser> list = findListByUid(uid);

        if (list.size() < 1) {
            return null;
        }

        HashMap<Integer, StoreGiftCardUser> map = new HashMap<>();
        for (StoreGiftCardUser info : list) {
            map.put(info.getCardId(), info);
        }
        return map;
    }

    @Override
    public List<StoreGiftCardUser> findListByUid(Integer uid, PageParamRequest pageParamRequest) {

        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());

        LambdaQueryWrapper<StoreGiftCardUser> lqw = new LambdaQueryWrapper<>();

        lqw.eq(StoreGiftCardUser::getUid, uid);
        lqw.orderByDesc(StoreGiftCardUser::getId);
        return dao.selectList(lqw);
    }

    @Override
    public List<StoreGiftCardUser> getDeliverList() {

        LambdaQueryWrapper<StoreGiftCardUser> lqw = new LambdaQueryWrapper<>();

        lqw.isNull(StoreGiftCardUser::getBelongId);
        lqw.isNull(StoreGiftCardUser::getUid);
        lqw.eq(StoreGiftCardUser::getStatus, 0);
        lqw.eq(StoreGiftCardUser::getReceiveStatus, 0);
        lqw.select(StoreGiftCardUser::getId, StoreGiftCardUser::getCardType, StoreGiftCardUser::getType,
                StoreGiftCardUser::getUseType, StoreGiftCardUser::getCardNum, StoreGiftCardUser::getName);

        return dao.selectList(lqw);
    }

    @Override
    public Boolean receiveGiftCard(UserGiftCardReceiveRequest request) {

        Integer uid = userService.getUserIdException();

        if (request.getCardNum() != null && request.getId() != null) {
            LambdaUpdateWrapper<StoreGiftCardUser> luw = new LambdaUpdateWrapper<>();
            luw.eq(StoreGiftCardUser::getCardNum, request.getCardNum());
            luw.eq(StoreGiftCardUser::getPass, request.getId());
            luw.set(StoreGiftCardUser::getUid, uid);
            return dao.update(null, luw) > 0;
        }
        return false;
    }

    @Override
    public Integer getUseCount(Integer uid) {

        LambdaQueryWrapper<StoreGiftCardUser> lqw = new LambdaQueryWrapper<>();
        lqw.eq(StoreGiftCardUser::getCardType, 1);
        lqw.eq(StoreGiftCardUser::getBelongId, uid);
        lqw.isNull(StoreGiftCardUser::getUid);
        lqw.eq(StoreGiftCardUser::getStatus, 0);
        lqw.or().eq(StoreGiftCardUser::getUid, uid);
        lqw.eq(StoreGiftCardUser::getCardType, 1);
        lqw.eq(StoreGiftCardUser::getStatus, 0);
        List<StoreGiftCardUser> cardUserList = dao.selectList(lqw);

        if (CollUtil.isEmpty(cardUserList)) {
            return 0;
        }
        Date date = DateUtil.nowDateTime();
        for (int i = 0; i < cardUserList.size();) {
            StoreGiftCardUser cardUser = cardUserList.get(i);
            //判断是否在使用时间内
            if (ObjectUtil.isNotNull(cardUser.getStartTime()) && ObjectUtil.isNotNull(cardUser.getEndTime())) {
                if (date.compareTo(cardUser.getEndTime()) >= 0) {
                    cardUserList.remove(i);
                    continue;
                }
            }
            i++;
        }
        return CollUtil.isEmpty(cardUserList) ? 0 : cardUserList.size();
    }

    @Override
    public void expireTask() {

        LambdaQueryWrapper<StoreGiftCardUser> lqw = new LambdaQueryWrapper<>();
        lqw.eq(StoreGiftCardUser::getStatus, 0);
        lqw.eq(StoreGiftCardUser::getReceiveStatus, 2);
        List<StoreGiftCardUser> cardUserList = dao.selectList(lqw);
        if (CollUtil.isEmpty(cardUserList)) {
            return;
        }
        List<StoreGiftCardUser> updateList = CollUtil.newArrayList();
        String nowDateStr = DateUtil.nowDate(Constants.DATE_FORMAT);
        cardUserList.forEach(card -> {
            if (ObjectUtil.isNotNull(card.getEndTime())) {
                String expireDateStr = DateUtil.dateToStr(card.getExpiredTime(), Constants.DATE_FORMAT);
                if (DateUtil.compareDate(nowDateStr, expireDateStr, Constants.DATE_FORMAT) >= 0) {
                    card.setReceiveStatus(1);
                    card.setExpiredTime(null);
                    updateList.add(card);
                }
            }
        });
        if (CollUtil.isEmpty(updateList)) {
            return;
        }
        boolean update = updateBatchById(updateList);
        if (!update) throw new CrmebException("批量更新礼品卡领取过期动作失败");
    }

    @Override
    public void overdueTask() {

        LambdaQueryWrapper<StoreGiftCardUser> lqw = new LambdaQueryWrapper<>();
        lqw.eq(StoreGiftCardUser::getStatus, 0);
        List<StoreGiftCardUser> cardUserList = dao.selectList(lqw);
        if (CollUtil.isEmpty(cardUserList)) {
            return;

        }
        // 判断卡片是否过期
        List<StoreGiftCardUser> updateList = CollUtil.newArrayList();
        String nowDateStr = DateUtil.nowDate(Constants.DATE_FORMAT);
        cardUserList.forEach(card -> {
            if (ObjectUtil.isNotNull(card.getEndTime())) {
                String endDateStr = DateUtil.dateToStr(card.getEndTime(), Constants.DATE_FORMAT);
                if (DateUtil.compareDate(nowDateStr, endDateStr, Constants.DATE_FORMAT) >= 0) {
                    card.setStatus(2);
                    updateList.add(card);
                }
            }
        });

        if (CollUtil.isEmpty(updateList)) {
            return;
        }
        boolean update = updateBatchById(updateList);
        if (!update) throw new CrmebException("批量更新礼品卡过期动作失败");
    }

    @Override
    public MyRecord buyMemberGiveAway(Integer cardId, Integer uid, Integer nums) {
        return null;
    }

    @Override
    public StoreGiftCardInfoResponse useCard(UserGiftCardReceiveRequest request) {

        LambdaQueryWrapper<StoreGiftCardUser> lqw = new LambdaQueryWrapper<>();

        Integer userId = userService.getUserIdException();
        if (request.getId() != null) {
            lqw.eq(StoreGiftCardUser::getId, request.getId());
            lqw.eq(StoreGiftCardUser::getBelongId, userId);
            lqw.isNull(StoreGiftCardUser::getUid);
            lqw.or()
                    .eq(StoreGiftCardUser::getUid, userId)
                    .eq(StoreGiftCardUser::getId, request.getId());
        } else {
            lqw.eq(StoreGiftCardUser::getCardNum, request.getCardNum());
            lqw.eq(StoreGiftCardUser::getPass, SecureUtil.sha256(request.getPass()));
        }

        StoreGiftCardUser cardUser = dao.selectOne(lqw);
        if (cardUser == null) {
            throw new CrmebException("查无此卡");
        }

        if (cardUser.getStatus() != 0) {
            throw new CrmebException("该卡已使用/过期");
        }

        redisUtil.set(RedisConstatns.USER_USE_GIFT_CARD_KEY + userId, cardUser.getId());

        StoreGiftCard giftCard = giftCardDao.selectById(cardUser.getCardId());
        List<StoreProduct> productList = null;
        List<Category> categoryList = null;
        if (StrUtil.isNotBlank(giftCard.getPrimaryKey()) && giftCard.getUseType() > 1) {
            List<Integer> primaryKeys = CrmebUtil.stringToArray(giftCard.getPrimaryKey());
            if (giftCard.getUseType() == 2) {
                productList = storeProductService.getListInIds(primaryKeys);
            } else if (giftCard.getUseType() == 3) {
                categoryList = categoryService.getByIds(primaryKeys);
            }
        }

        StoreGiftCardRequest giftCardRequest = new StoreGiftCardRequest();
        BeanUtil.copyProperties(giftCard, giftCardRequest);

        return new StoreGiftCardInfoResponse(giftCardRequest, productList, categoryList);
    }

    @Override
    public boolean updateStatus(Integer id) {

        StoreGiftCardUser cardUser = getById(id);
        if (cardUser.getStatus() != 0 || cardUser.getReceiveStatus() >= 2) {
            throw new CrmebException("该卡片不可使用,已经失效,被使用或者被送出");
        }

        LambdaUpdateWrapper<StoreGiftCardUser> luw = new LambdaUpdateWrapper<>();
        luw.set(StoreGiftCardUser::getStatus, 1);
        luw.set(StoreGiftCardUser::getUseTime, DateUtil.nowDateTime());
        luw.eq(StoreGiftCardUser::getId, id);

        return dao.update(null, luw) > 0;
    }

    private List<StoreGiftCardUser> findListByUid(Integer uid) {

        LambdaQueryWrapper<StoreGiftCardUser> lqw = new LambdaQueryWrapper<>();
        lqw.eq(StoreGiftCardUser::getUid, uid);
        return dao.selectList(lqw);
    }

    /**
     * 移动端列表
     * @param type 类型，usable-可用，unusable-不可用
     * @param userId 用户id
     * @param pageParamRequest 分页类参数
     * @return List<StoreCouponUser>
     */
    private List<StoreGiftCardUser> getH5List(String type, Integer userId, PageParamRequest pageParamRequest) {
        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());

        LambdaQueryWrapper<StoreGiftCardUser> lqw = new LambdaQueryWrapper<>();

        lqw.eq(StoreGiftCardUser::getCardType, 1);
        lqw.eq(StoreGiftCardUser::getBelongId, userId);
        lqw.isNull(StoreGiftCardUser::getUid);
        if (type.equals("usable")) {
            lqw.eq(StoreGiftCardUser::getStatus, CouponConstants.STORE_COUPON_USER_STATUS_USABLE);
            lqw.orderByDesc(StoreGiftCardUser::getId);
        }
        if (type.equals("unusable")) {
            lqw.gt(StoreGiftCardUser::getStatus, CouponConstants.STORE_COUPON_USER_STATUS_USABLE);
            lqw.last(StrUtil.format(" order by case `status` when {} then {} when {} then {} when {} then {} end", 0, 1, 1, 2, 2, 3));
        }
        lqw.or().eq(StoreGiftCardUser::getUid, userId);
        lqw.eq(StoreGiftCardUser::getCardType, 1);
        if (type.equals("usable")) {
            lqw.eq(StoreGiftCardUser::getStatus, CouponConstants.STORE_COUPON_USER_STATUS_USABLE);
            lqw.orderByDesc(StoreGiftCardUser::getId);
        }
        if (type.equals("unusable")) {
            lqw.gt(StoreGiftCardUser::getStatus, CouponConstants.STORE_COUPON_USER_STATUS_USABLE);
            lqw.last(StrUtil.format(" order by case `status` when {} then {} when {} then {} when {} then {} end", 0, 1, 1, 2, 2, 3));
        }

        List<StoreGiftCardUser> cardUserList = dao.selectList(lqw);
        if (CollUtil.isEmpty(cardUserList)) {
            return CollUtil.newArrayList();
        }
        return cardUserList;
    }
}
